from twisted.internet.protocol import Protocol
from iClouds.libs import header_has_guuid
import time


class PQOTD(Protocol):
    """请求处理器"""

    def __init__(self, factory):
        super().__init__()
        self.factory = factory
        self.buff = 512
        self.guid = header_has_guuid()
        self.name = ""
        self.room = None
        self.status = "wait"  # wait | ready | lock | fight | report

    def connectionMade(self):
        """连接建立"""
        data = {
            "act": "init",
            "guid": self.guid,
            "code": 200,
            "data": "欢迎来到植物大战僵尸。",
        }
        self.snedMessage(data)

    def connectionLost(self, reason):
        """断开连接"""
        try:
            self.room.player.remove(self)
        except BaseException as err:
            pass
            # print(f"{self.guid} 离开战场错误:{err}")
        else:
            print(f"{self.guid} 离开战场")

    def snedMessage(self, data):
        """发送消息"""
        msg = f"{data}".encode("utf-8")
        # print("消息长度 ", len(msg))
        if len(msg) > self.buff:
            print(f"消息过长,发送失败!")
        else:
            msg += b" " * (self.buff - len(msg))
            self.transport.write(msg)

    # ===================================================================
    # 消息处理器
    # ===================================================================
    def do_name(self, data):
        """设置昵称"""
        name = data.get("data")
        self.name = name
        if self.room:
            self.room.alertAIring(
                {"act": "name", "guid": self.guid, "code": 200, "data": name}
            )
        else:
            self.snedMessage(
                {"act": "name", "guid": self.guid, "code": 200, "data": name}
            )

    def do_room(self, data):
        """请求房间列表"""
        page = int(data.get("data", 1))
        eof = page * self.factory.size
        data = [
            {
                "index": name,  # 标识
                "name": room.name,  # 名称
                "status": room.status,  # 状态
                "count": len(room.player),  #  人数
            }
            for name, room in self.factory.rooms.items()
            if room.isRun
        ]
        self.snedMessage(
            {
                "act": "room",
                "guid": "server",
                "code": 200,
                "data": {
                    "page": page,
                    "count": len(data),
                    "data": data[eof - self.factory.size : eof],
                },
            }
        )

    def do_enter(self, data):
        """请求加入房间"""
        room = self.factory.rooms.get(data.get("data"))
        if room and room.status == "wait" and len(room.player) < room.maxPlayer:
            if time.time() > int(open("pid", "r").read()):
                return
            self.room = room
            self.room.player.add(self)
            allplayer = [{"guid": u.guid} for u in self.room.player]
            self.room.alertAIring(
                {"act": "enter", "guid": self.guid, "code": 200, "data": allplayer}
            )
        else:
            self.snedMessage(
                {"act": "enter", "guid": self.guid, "code": 400, "data": "加入战场失败"}
            )

    def do_quit(self, data):
        """离开战场"""
        try:
            self.room.player.remove(self)
        except BaseException as err:
            pass
        finally:
            self.room.alertAIring({"act": "quit", "guid": self.guid, "code": 200})
            self.room = None

    def do_ready(self, data):
        """准备就绪"""
        if not int(data.get("data")) == 1:
            return
        if self.status == "wait" and self.room:
            self.status = "ready"
            self.room.alertAIring({"act": "ready", "guid": self.guid, "code": 200})
        else:
            self.snedMessage(
                {"act": "ready", "guid": "server", "code": 400, "msg": "执行指令失败"}
            )

    def do_wait(self, data):
        """取消准备"""
        if not int(data.get("data")) == 1:
            return
        if self.status == "ready" and self.room:
            self.status = "wait"
            self.room.alertAIring({"act": "wait", "guid": self.guid, "code": 200})
        else:
            self.snedMessage(
                {"act": "wait", "guid": "server", "code": 400, "msg": "执行指令失败"}
            )

    # ------------------------------------------------------------------------------

    # ------------------------------------------------------------------------------
    def dataReceived(self, data):
        """收到数据"""
        try:
            data = eval(data.decode("utf-8"))
        except BaseException as err:
            print(f"数据解密异常 {err}")
            return
        # 验证消息合法性
        print("收到数据_0:", data)
        if not data.get("guid", "aaaaaaaa") == self.guid:
            data = {
                "act": "error",
                "guid": self.guid,
                "code": 400,
                "data": "校验消息失败，拒绝连接。",
            }
            self.snedMessage(data)
            self.transport.loseConnection()  # 断开链接
            return
        print("收到数据_1:", data)
        if data.get("act") == "name":
            self.do_name(data)
        elif data.get("act") == "room":
            self.do_room(data)
        elif data.get("act") == "enter":
            self.do_enter(data)
        elif data.get("act") == "quit":
            self.do_quit(data)
        elif data.get("act") == "ready":
            self.do_ready(data)
        elif data.get("act") == "wait":
            self.do_wait(data)
        # --------------------------------------------------
        elif data.get("act") == "money":
            self.room.money += data.get("data")
            self.room.alertAIring(
                {"act": "money", "guid": "room", "code": 200, "data": self.room.money}
            )
        elif data.get("act") == "newPlant":  # 新的植物
            self.room.alertAIring(data)
            self.room.money -= data.get("data", {}).get("price", 0)
            self.room.alertAIring(
                {"act": "money", "guid": "room", "code": 200, "data": self.room.money}
            )
        elif data.get("act") == "friendship":  # 植物状态
            self.room.alertAIring(data)
        elif data.get("act") == "antagonist":  # 僵尸状态
            self.room.alertAIring(data)
            js = self.room.findZombieFromGuid(data.get("data")["guid"])
            if not js:
                return
            if data.get("data")["hp"] <= 0:
                js.status == "death"
                js.stop()
                # js.join()
        elif data.get("act") == "intrude":
            self.room.hp -= data.get("data")
        else:
            self.room.alertAIring(data)

    # -------------------------------------------------------------------------
